// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2007
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class GradientXCentralDifference : ImageFilter//, IGraylevelImageFilter
    {
        #region Fields
        //private string flag = "[Image -> Gradient -> Gradient X Central Difference]";
        #endregion

        #region Constructor
        public GradientXCentralDifference()
        {
            _flag = "[Image -> Gradient -> Gradient X Central Difference]";
            _normalize = true;
        }
        #endregion

        //#region Properties
        //public string Log() { return _log; }
        //public string Flag() { return flag; }
        //#endregion

        #region Apply filter
        //public Bitmap ApplyGraylevelImageFilter(Bitmap srcImage) { return Apply(srcImage, out _log); }        
        //public PZMath_matrix ApplyDoubleGraylevelImageFilter(PZMath_matrix srcMatrix) { return ApplyDouble(srcMatrix, out _log); }

        //private Bitmap Apply(Bitmap srcImage, out string logText)
        //{
        //    PZMath_matrix srcMatrix = _converter.ConvertGraylevelBitmapToMatrix(srcImage);
        //    PZMath_matrix dstMatrix = ApplyDouble(srcMatrix, out logText);
        //    Bitmap dstImage = _converter.ConvertMatrixToGraylevelBitmap(dstMatrix, true);
        //    return dstImage;
        //}     

        protected override PZMath_matrix ApplyDoubleGraylevelImageFilter(PZMath_matrix srcMatrix, out string logText)
        {
            #region source and dst matrix
            // get source
            int width = srcMatrix.ColumnCount;
            int height = srcMatrix.RowCount;

            // create dstMatrix
            PZMath_matrix dstMatrix = new PZMath_matrix(height, width);
            int heightM1 = height - 1;
            int widthM1 = width - 1;
            int heightM2 = height - 2;
            int widthM2 = width - 2;
            #endregion

            #region apply filter, X direction
            // for each pixel
            for (int y = 0; y < height; y++)
            {
                for (int x = 1; x < widthM1; x++)
                {
                    dstMatrix[y, x] = (srcMatrix[y, x + 1] - srcMatrix[y, x - 1]) / 2.0;
                }
            }
            #endregion

            #region boundary, right and left boundaries
            for (int y = 0; y < height; y++)
            {
                dstMatrix[y, 0] = srcMatrix[y, 1] - srcMatrix[y, 0];
                dstMatrix[y, widthM1] = srcMatrix[y, widthM1] - srcMatrix[y, widthM2];
            }
            #endregion
            logText = "succeeds.";
            return dstMatrix;
        } // ApplyDoubleGraylevelImageFilter()

        protected override PZMath_matrix[] ApplyDoubleColourImageFilter(PZMath_matrix[] srcMatrix, out string logText)
        {
            // TODO: verify this function

            #region source and dst matrix
            // get source
            PZMath_matrix srcR = srcMatrix[0];
            PZMath_matrix srcG = srcMatrix[1];
            PZMath_matrix srcB = srcMatrix[2];

            int width = srcR.ColumnCount;
            int height = srcR.RowCount;

            // create dstMatrix
            PZMath_matrix[] dstMatrix = new PZMath_matrix[3];
            dstMatrix[0] = new PZMath_matrix(height, width);
            dstMatrix[1] = new PZMath_matrix(height, width);
            dstMatrix[2] = new PZMath_matrix(height, width);
            PZMath_matrix dstR = dstMatrix[0];
            PZMath_matrix dstG = dstMatrix[1];
            PZMath_matrix dstB = dstMatrix[2];
            int heightM1 = height - 1;
            int widthM1 = width - 1;
            int widthM2 = width - 2;
            #endregion

            #region apply filter, X direction
            // for each pixel
            for (int y = 0; y < height; y++)
            {
                for (int x = 1; x < widthM1; x++)
                {
                    dstR[y, x] = (srcR[y, x + 1] - srcR[y, x - 1]) / 2.0;
                    dstG[y, x] = (srcG[y, x + 1] - srcG[y, x - 1]) / 2.0;
                    dstB[y, x] = (srcB[y, x + 1] - srcB[y, x - 1]) / 2.0;
                }
            }
            #endregion

            #region boundary, right and left boundaries
            for (int y = 0; y < height; y++)
            {
                dstR[y, 0] = srcR[y, 1] - srcR[y, 0];
                dstG[y, 0] = srcG[y, 1] - srcG[y, 0];
                dstB[y, 0] = srcB[y, 1] - srcB[y, 0];
                dstR[y, widthM1] = srcR[y, widthM1] - srcR[y, widthM2];
                dstG[y, widthM1] = srcG[y, widthM1] - srcG[y, widthM2];
                dstB[y, widthM1] = srcB[y, widthM1] - srcB[y, widthM2];
            }
            #endregion
            logText = "succeeds.";
            return dstMatrix;
        } // ApplyDoubleColourImageFilter()
        #endregion
    }
}
